/* eslint-disable */
import FinModel from '../js/FinModel.js'
import Map1 from '../js/Map1.js'
export const mixin_fishBone = {
  mixins: [],
  /** 组件数据 */
  data() {
    return {
      defaults: {
        /*json数据！重要，必填*/
        jsonData: null,
        /*鱼骨主题，用来修改样式，默认是1,目前不支持 */
        theme: 'default',
        /*是否可以拖动，默认是true */
        dragable: true,
        /*是否显示工具条 */
        showToolbar: true,
        /* 画布的大小 */
        canvasSize: [800, 400],
        /*  鱼头左侧中心坐标  */
        //mainFishTopPosition: null,
        /* debug模式 */
        debug: false,
        sceneBackgroundImage: null,
        /**
         * 下面3个事件分别是点击、右键点击、鼠标悬浮，可回调如下函数
         * function (node) {
         * alert(node.text);
         * }
         */
        clickNodeFunction: null,
        rClickNodeFunction: null,
        mouseOverFunction: null
      },
      /* 基础点的集合,最后进行渲染　*/
      baseNodeArray: new Array(),
      /* 鱼翅集合,最后进行渲染 */
      FishBoneMap: new Map1(),
      /* 骨干鱼翅上两个子鱼翅为一组，算最大值，需要了解一共有多少段，每段的最大长度 */
      FinTeamMap: new Map1(),

      FinDeepTempMap: new Map1(),
      /* 画布 */
      stage: '',
      scene: '',
      /*默认支持鱼骨层级*/
      defaultBonesDeep: 3,
      /*主要鱼骨长度*/
      mainBoneLength: 0,
      /*  鱼头上侧坐标    */
      mainFishTopPosition: [],
      /*  鱼头中心中心坐标    */
      mainFishPosition: [],
      /*  鱼尾巴中心中心坐标    */
      mainFishTailPosition: [],
      /*  鱼尾巴图片坐标    */
      mainFishTailImagePosition: [],
      /*  鱼头id */
      mainFishId: 1,
      /*  鱼头长度    */
      mainHeadLength: 0,
      /*  鱼头文字    */
      mainHeadText: '',
      /* 默认树的深度是-1 */
      fishBoneDeep_: -1,
      iCount: 1,
      sign3: Math.sqrt(3),
      /*默认主要鱼骨的步长*/
      defaultBoneStepLength: 150,
      /*默认鱼头高度 a4*/
      defaultFishHeadHeight: 64,
      /*图像百分比系数 100%*/
      basePercent: 1,
      /*从鱼头X轴到第一个点的默认距离 a1*/
      defaultHeadToFirstNodeLength: 50,
      /*鱼尾 a16*/
      defaultFishTail: 50,
      /*默认一级鱼骨交叉距离 a2*/
      defaultCrossStep: 30,
      /*默认二级鱼骨一个汉字的长度 h1*/
      defaultCharLengthForLevel1: 16,
      /*默认二级鱼骨一个汉字的长度 h1*/
      defaultCharLengthForLevel2: 15,
      /*默认二级鱼骨以下一个汉字的长度 */
      defaultCharLengthForLevel3AndLow: 12,
      /*默认二级鱼骨以下一个英文的长度 */
      defaultUpEnglishLength: 8,
      /*默认一级字符长度*/
      defaultSignLengthForLevel1: 10,
      /*默认二级鱼骨一个字符的长度 h1*/
      defaultSignLength: 5,
      /*4级骨头每个鱼翅的距离 a13*/
      defaultLevel4Step: 15,
      deep: 1,
      /* 鱼翅在上或在下,true是上，false是下  */
      upOrDown: false,
      /* 用于计算２级鱼骨的第几个节点，当是奇数的时候增加小组*/
      nodeIndex: 0,
      /* 鱼翅小组，每两个二级鱼翅为一个小组　*/
      teamIndex: 1,
      datIndex: 1,
      // 二级坐标集合
      twoLevelArray: [],
      // 二级节点集合
      twoLevelNodeArray: []
    }
  },
  /** 计算 */
  computed: {},
  /** 组件方法 */
  methods: {
    /*获取字符串中文数量*/
    getChineseCount(str) {
      let count = 0
      for (let i = 0; i < str.length; i++) {
        if (str.charCodeAt(i) > 255) {
          count++
        }
      }
      return count
    },
    /*获取字符串英文数量*/
    getUpEnglishCount(str) {
      let count = 0
      for (let i = 0; i < str.length; i++) {
        if (str.charCodeAt(i) >= 65 && str.charCodeAt(i) <= 90) {
          count++
        }
      }
      return count
    },
    /* 获取鱼头的长度   */
    getHeadLength(name) {
      let chineseCount = this.getChineseCount(name)
      let upEnglishCount = this.getUpEnglishCount(name)
      return chineseCount * this.defaultCharLengthForLevel1 + upEnglishCount * this.defaultUpEnglishLength + (name.length - chineseCount - upEnglishCount) * this.defaultSignLengthForLevel1 + 40
    },
    /* 递归整棵树,同时计算树的最大深度，计算鱼头的长度 */
    deepLoop_(dat) {
      if (this.iCount == 1) {
        this.mainFishId = dat.id
        this.FinDeepTempMap.put(dat.id, 1)
        this.mainHeadText = dat.name
        this.mainHeadLength = this.getHeadLength(this.mainHeadText)
      } else {
        if (this.FinDeepTempMap.containsKey(dat.fid)) {
          this.deep = this.FinDeepTempMap.get(dat.fid) + 1
          this.FinDeepTempMap.put(dat.id, this.deep)
        }
      }
      this.iCount++
      this.compare_(this.deep)
      if (dat.children) {
        for (let i = 0; i < dat.children.length; i++) {
          this.deepLoop_(dat.children[i])
        }
      }
    },
    /* 比较每个节点的深度，重复覆盖默认值，取最大 */
    compare_(deep) {
      if (deep != null) {
        this.fishBoneDeep_ = deep > this.fishBoneDeep_ ? deep : this.fishBoneDeep_
      }
    },
    /* 递归整棵树 */
    getBoneDeep() {
      for (let i = 0; i < this.options.jsonData.length; i++) {
        this.deepLoop_(this.options.jsonData[i])
      }
      return this.fishBoneDeep_
    },
    /* 验证树的深度 */
    validateBoneDeep() {
      let flag = this.getBoneDeep() > this.defaultBonesDeep
      if (flag) {
        alert('对不起，目前仅支持' + this.defaultBonesDeep + '级鱼骨!')
      }
      return !flag
    },
    /* validate */
    validate() {
      if (!this.options.jsonData) {
        alert('json数据不能为空！')
        return
      }
      if (!this.validateBoneDeep()) {
        return
      }
    },
    getFishBoneNode(position) {
      let jNode = new JTopo.Node('')
      jNode.shadow = false
      jNode.showSelected = false
      jNode.dragable = false
      if (position && position.length > 1) {
        jNode.setLocation(position[0], position[1])
      }
      jNode.setSize(0, 0)
      if (this.options.debug) {
        jNode.setSize(5, 5)
      }
      return jNode
    },

    getFishBoneLinkByNode(node_, jNodeFrom, jNodeTo, text, color) {
      let link = new JTopo.Link(jNodeTo, jNodeFrom, text)
      link.lineWidth = 0.9
      link.zIndex = 10
      link.dragable = false
      link.shadow = false
      link.showSelected = false
      // link.fillColor = 'black'
      link.strokeColor = '0,0,0'
      link.arrowsRadius = 3
      if (node_.lineColor_) {
        link.fillColor = node_.lineColor_
        link.strokeColor = node_.lineColor_
      }
      return link
    },
    getFishTextNode(node) {
      let textNode
      /*链接节点或文字节点*/
      if (node.level_ == 2) {
        textNode = new JTopo.LinkNode('')
      } else if (node.link_) {
        textNode = new JTopo.LinkNode(node.name_)
        textNode.href = node.link_
        textNode.target = '_blank'
      } else {
        textNode = new JTopo.TextNode(node.name_)
      }
      textNode.fontColor = '40,40,40'
      /*2级节点文字特殊*/
      if (node.level_ == 2) {
        // textNode.font = '14px 黑体'
        // textNode.fontColor = '40,40,40'
        // textNode.shadow = true
        // textNode.shadowBlur = 9
        //textNode.selected=true;
      } else {
        textNode.font = ' 700 12px 黑体'
        textNode.shadow = false
      }
      if (node.nameColor_) {
        textNode.fontColor = node.nameColor_
      }
      /*文字点击事件*/
      if (this.options.clickNodeFunction) {
        textNode.click(function() {
          this.options.clickNodeFunction(this)
        })
      }
      /*右键点击事件*/
      if (this.options.rClickNodeFunction) {
        textNode.addEventListener('mouseup', function(event) {
          if (event.button == 2) {
            this.options.rClickNodeFunction(this)
          }
        })
      }
      /*鼠标划上事件*/
      if (this.mouseOverFunction) {
        textNode.addEventListener('mouseover', function(event) {
          this.options.mouseOverFunction(this)
        })
      }
      textNode.dragable = false
      textNode.rotate = node.rotate_
      return textNode
    },
    /*初始化画布容器*/
    initHtmlCanvas() {
      this.mainFishTopPosition = [this.options.canvasSize[0] * 0.98 - this.mainHeadLength, this.options.canvasSize[1] * 0.5 - this.defaultFishHeadHeight / 2]
      this.mainFishPosition = [this.mainFishTopPosition[0], this.mainFishTopPosition[1] + this.defaultFishHeadHeight / 2]
      // $this.prepend("<canvas width='" + options.canvasSize[0] + "' height='" + options.canvasSize[1] + "' id='canvas__'></canvas>");
    },

    /*初始化JTopo画布*/
    initJtoPoScene() {
      this.stage = new JTopo.Stage(document.getElementById('canvasBak'))
      this.scene = new JTopo.Scene(this.stage)
      if (this.options.sceneBackgroundImage) {
        this.scene.background = options.sceneBackgroundImage
      }
      if (!this.options.dragable) {
        this.scene.mode = 'select'
        this.scene.areaSelect = false
      }
    },
    initFinModels(dat) {
      let fin = new FinModel(dat.id, dat.fid, dat.name, this.upOrDown, dat.fontColor, dat.lineColor, dat.link)
      if (this.datIndex == 1) {
        fin.setLevel_(1)
      } else {
        if (this.FishBoneMap.containsKey(fin.getFid_())) {
          fin.setLevel_(this.FishBoneMap.get(fin.getFid_()).getLevel_() + 1)
        }
      }
      this.FishBoneMap.put(fin.getId_(), fin)
      this.datIndex++
      //修改算法
      //fin.setLevel_(this.getDeepByFinModel(fin));

      //2级叶子节点需要考虑分组切换
      if (fin.getLevel_() == 2) {
        this.nodeIndex++
        if (this.nodeIndex % 2 == 1) {
          if (this.nodeIndex != 1) {
            this.teamIndex++
          }
          this.FinTeamMap.put(this.teamIndex, 0)
        }
      }
      fin.setFinTeam_(this.teamIndex)
      if (fin.getLevel_() == 2) {
        this.upOrDown = !this.upOrDown
        fin.setUpOrDown_(this.upOrDown)
      }
      if (this.upOrDown) {
        if (fin.level_ % 2 == 0) {
          fin.setRotate_(Math.PI / 3)
        }
      } else {
        if (fin.level_ % 2 == 0) {
          fin.setRotate_(Math.PI / 1.5)
        }
      }
      if (dat.children) {
        fin.setLeaf_(false)
        for (let i = 0; i < dat.children.length; i++) {
          this.initFinModels(dat.children[i])
        }
      } else {
        fin.setLeaf_(true)
      }
    },

    /* 将所有json对象转化成map,key是id,value是fin对象 */
    initFinModelMap() {
      for (let i = 0; i < this.options.jsonData.length; i++) {
        this.initFinModels(this.options.jsonData[i])
      }
    },

    /* 3级鱼翅长度算法 */
    level3LengthArithmetic(c) {
      let chineseCount = this.getChineseCount(c)
      let upEnglishCount = this.getUpEnglishCount(c)
      return chineseCount * this.defaultCharLengthForLevel3AndLow + upEnglishCount * this.defaultUpEnglishLength + (c.length - chineseCount - upEnglishCount) * this.defaultSignLength + 30
    },

    /* 2级鱼翅长度算法 */
    level2LengthArithmetic(c) {
      let chineseCount = this.getChineseCount(c)
      let upEnglishCount = this.getUpEnglishCount(c)
      return chineseCount * this.defaultCharLengthForLevel2 + upEnglishCount * this.defaultUpEnglishLength + (c.length - chineseCount - upEnglishCount) * this.defaultSignLength
    },

    /* 线上文字坐标算法！重要  */
    levelPositionArithmetic(node) {
      let position = []
      let x = 0
      let y = 0
      let offset = 0
      if (node.level_ == 2) {
        if (node.upOrDown_) {
          let cc = this.getChineseCount(node.name_)
          offset = 0 - (cc * 12 + (node.name_.length - cc) * 6) / 2 + 15
          x = node.toNodePosition_[0] + (node.fromNodePosition_[0] - node.toNodePosition_[0]) / 2 + offset
          y = node.fromNodePosition_[1] - (node.fromNodePosition_[1] - node.toNodePosition_[1]) / 2
        } else {
          let cc = this.getChineseCount(node.name_)
          offset = 0 - (cc * 12 + (node.name_.length - cc) * 6) / 2 + 10
          x = node.toNodePosition_[0] + (node.fromNodePosition_[0] - node.toNodePosition_[0]) / 2 + offset
          y = node.fromNodePosition_[1] + (node.toNodePosition_[1] - node.fromNodePosition_[1]) / 2
        }
      } else if (node.level_ == 3) {
        x = node.toNodePosition_[0] + 13
        //x = node.toNodePosition_[0] + (node.fromNodePosition_[0] - node.toNodePosition_[0]) / 2 - 22;
        y = node.fromNodePosition_[1] - (node.fromNodePosition_[1] - node.toNodePosition_[1]) / 2 - 16
      }
      position = [x, y]
      return position
    },

    /* 骨干鱼骨每个team的最大长度算法 */
    setTeamMaxLengthFinLength(fin, finLength) {
      let oldLength = this.FinTeamMap.get(fin.getFinTeam_())
      if (finLength > oldLength) {
        this.FinTeamMap.put(fin.getFinTeam_(), finLength + 25)
      }
    },

    /* 重点方法，初始化下一级、下下级的最大长度，用于计算鱼翅坐标 */
    initNextLevelCount() {
      let arr = this.FishBoneMap.values()
      for (let i = arr.length - 1; i >= 0; i--) {
        if (arr[i].fid_ != 0) {
          let f = this.FishBoneMap.get(arr[i].id_)
          let fParent = this.FishBoneMap.get(arr[i].fid_)
          fParent.setNextLevelCount_(fParent.getNextLevelCount_() + 1)
          switch (f.getLevel_()) {
            case 2:
              //   let length = this.level2LengthArithmetic(arr[i].name_)
              let length = 75
              if (f.getNextLevelCount_() != 0) {
                length = length + (f.getNextLevelCount_() - 1) * this.defaultCrossStep
              }
              f.setFinLength_(length)
              break
            case 3:
              /*父父节点*/
              let ffParent = this.FishBoneMap.get(fParent.getFid_())
              /*3级文字长度*/
              var length = this.level3LengthArithmetic(arr[i].name_)
              /*如果有4级，那么长度是3级文字长度+4级算法*/
              if (f.getNextLevelCount_() != 0) {
                length = length + f.getNextLevelCount_() * this.defaultLevel4Step
              }
              /*设置3级文字长度*/
              f.setFinLength_(length)
              /*骨干鱼骨根据组判断最长鱼翅*/
              this.setTeamMaxLengthFinLength(f, length)
              /*父级节点设置下级最长鱼翅*/
              fParent.setNextLevelMaxLength_(fParent.getNextLevelMaxLength_() > f.getFinLength_() ? fParent.getNextLevelMaxLength_() : f.getFinLength_())
              fParent.getChildrenNode_().push(f)
              break
          }
        }
      }
    },
    /*初始化整个鱼身的长度*/
    initMainBoneLength() {
      let length = 0
      let arr = this.FinTeamMap.values()
      for (let i = 0; i < arr.length; i++) {
        if (arr[i] == 0) {
          arr[i] = this.defaultBoneStepLength
        }
        length = length + arr[i]
      }
      this.mainBoneLength = length + this.defaultHeadToFirstNodeLength + this.defaultFishTail + 130
    },

    /*鱼头坐标*/
    initMainBonePositions() {
      // 鱼头图片位置调整
      this.mainFishTopPosition[1] = this.mainFishTopPosition[1] - 65
      let jNode = this.getFishBoneNode(this.mainFishTopPosition)
      jNode.setImage('../../../static/images/fishbone/head.png', false)
      // jNode.setImage('@/static/images/fishbone/head.png', false)
      jNode.zIndex = 20
      jNode.setSize(200, 200)
      //   jNode.setSize(this.mainHeadLength, this.defaultFishHeadHeight)
      //jNode.scalaX=Math.random();
      this.baseNodeArray.push(jNode)
    },

    /*初始化骨干鱼骨*/
    initMainBone() {
      this.initMainBoneLength()
      this.initMainBonePositions()
      /*鱼头左侧中心*/
      let jNodeFrom = this.getFishBoneNode(this.mainFishPosition)
      this.baseNodeArray.push(jNodeFrom)
      /*鱼头文字*/
      let textNode = new JTopo.TextNode(this.FishBoneMap.get(this.mainFishId).name_)
      textNode.fontColor = '40,40,40'
      textNode.font = 'bold 16px 微软雅黑'
      textNode.shadow = false
      textNode.dragable = false
      textNode.setLocation(this.mainFishPosition[0] + 70, this.mainFishPosition[1] - 120)
      this.baseNodeArray.push(textNode)
      /*鱼尾*/
      this.mainFishTailPosition = [this.mainFishPosition[0] - this.mainBoneLength, this.mainFishPosition[1]]
      let jNodeTo = this.getFishBoneNode(this.mainFishTailPosition)
      this.baseNodeArray.push(jNodeTo)
      // 连线
      let newPosition = [this.mainFishPosition[0] + 100, this.mainFishPosition[1]]
      let jNodeNew = this.getFishBoneNode(newPosition)
      let link = new JTopo.Link(jNodeTo, jNodeNew)
      link.lineWidth = 2
      link.strokeColor = '0,0,0'
      link.arrowsRadius = 10
      link.zIndex = 100
      this.baseNodeArray.push(link)
      /*鱼身*/
      //   let bodyPosition = [this.mainFishPosition[0] - this.mainBoneLength - 10, this.mainFishPosition[1] - 8]
      //   let jNode = this.getFishBoneNode(bodyPosition)
      //   jNode.setImage('./static/body.png', false)
      //   jNode.zIndex = 9
      //   jNode.setSize(this.mainBoneLength + 10, 1)
      //   this.baseNodeArray.push(jNode)
      /*鱼尾图片*/
      this.mainFishTailImagePosition = [this.mainFishTailPosition[0] - 24, this.mainFishTailPosition[1] - 34]
      let jNodeTail = this.getFishBoneNode(this.mainFishTailImagePosition)
      //   jNodeTail.setImage('./static/tail.png', true)
      jNodeTail.zIndex = 10
      this.baseNodeArray.push(jNodeTail)
    },

    /*初始化2级鱼骨坐标*/
    initLevel2Position() {
      let arr = this.FishBoneMap.values()
      let k = 0
      let lastX = 0
      for (let i = 0; i < arr.length; i++) {
        if (arr[i].level_ === 2) {
          k++
          if (k === 1) {
            //X坐标
            lastX = this.mainFishPosition[0] - this.defaultHeadToFirstNodeLength
            arr[i].fromNodePosition_ = [lastX, this.mainFishPosition[1]]
            //Ｙ坐标
            arr[i].toNodePosition_ = [lastX - arr[i].finLength_ / 2, this.mainFishPosition[1] - (arr[i].finLength_ * this.sign3) / 2]
            this.twoLevelArray.push(arr[i].toNodePosition_)
            continue
          }
          if (k % 2 === 1) {
            //X坐标
            let l = this.FinTeamMap.get(arr[i].getFinTeam_() - 1)
            lastX = lastX - (l === 0 ? defaultBoneStepLength : l)
            arr[i].fromNodePosition_ = [lastX, this.mainFishPosition[1]]
            //Ｙ坐标
            arr[i].toNodePosition_ = [lastX - arr[i].finLength_ / 2, this.mainFishPosition[1] - (arr[i].finLength_ * this.sign3) / 2]
            this.twoLevelArray.push(arr[i].toNodePosition_)
          } else {
            //X坐标
            lastX = lastX - this.defaultCrossStep
            arr[i].fromNodePosition_ = [lastX, this.mainFishPosition[1]]
            //Ｙ坐标
            arr[i].toNodePosition_ = [lastX - arr[i].finLength_ / 2, this.mainFishPosition[1] + (arr[i].finLength_ * this.sign3) / 2]
            this.twoLevelArray.push(arr[i].toNodePosition_)
          }
        }
      }
    },

    /*初始化3级鱼骨坐标*/
    initLevel3Position() {
      let arr = this.FishBoneMap.values()
      for (let k = 0; k < arr.length; k++) {
        if (arr[k].level_ == 2) {
          /*例如1001*/
          let node = arr[k].childrenNode_
          let s = 0
          if (node.length > 0) {
            // for (let i = node.length - 1; i >= 0; i--) {
            for (let i = 0; i < node.length; i++) {
              if (node[i].upOrDown_) {
                node[i].fromNodePosition_ = [arr[k].toNodePosition_[0] + (s * this.defaultCrossStep) / 2 + 15 / 2, arr[k].toNodePosition_[1] + (s * this.defaultCrossStep * this.sign3) / 2 + (15 * this.sign3) / 2]
              } else {
                node[i].fromNodePosition_ = [arr[k].toNodePosition_[0] + (s * this.defaultCrossStep) / 2, arr[k].toNodePosition_[1] - (s * this.defaultCrossStep * this.sign3) / 2]
              }
              node[i].toNodePosition_ = [node[i].fromNodePosition_[0] - node[i].finLength_, node[i].fromNodePosition_[1]]
              s++
            }
          }
        }
      }
    },
    // 文字左平移
    leftDistance(name) {
      let length = this.level2LengthArithmetic(name)
      if (length < 110) {
        return length
      } else {
        return 100
      }
    },
    // 获取文字数组
    getNameArray(name) {
      let array = []
      let index = 0
      let length = name.length
      while ((length - index) / 8 >= 1) {
        let name1 = name.slice(index, index + 7)
        array.push(name1)
        index += 8
      }
      if (index != name.length) {
        array.push(name.slice(index))
      }
      return array
    },
    render() {
      for (let i = 0; i < this.baseNodeArray.length; i++) {
        if (this.baseNodeArray[i] != null) {
          this.scene.add(this.baseNodeArray[i])
        }
      }
      let arr = this.FishBoneMap.values()
      for (let i = 0; i < arr.length; i++) {
        if (arr[i].fromNodePosition_ && arr[i].toNodePosition_) {
          let jNodeFrom = this.getFishBoneNode(arr[i].fromNodePosition_)
          this.scene.add(jNodeFrom)
          let jNodeTo = this.getFishBoneNode(arr[i].toNodePosition_)
          this.scene.add(jNodeTo)
          let link = this.getFishBoneLinkByNode(arr[i], jNodeFrom, jNodeTo)
          this.scene.add(link)
          let textNode = this.getFishTextNode(arr[i])
          let position = this.levelPositionArithmetic(arr[i])
          textNode.setLocation(position[0], position[1])
          this.scene.add(textNode)
        }
        // 单独绘制二级文字节点
        let item = arr[i]
        if (item.level_ === 2) {
          let xDistance = this.leftDistance(item.name_)
          let nameArray = this.getNameArray(item.name_)
          // 起始点坐标
          let nodeNumber = nameArray.length
          let lineHeight = 15
          let twoLevelStartPosition = item.upOrDown_ ? [item.toNodePosition_[0] - xDistance, item.toNodePosition_[1] - lineHeight * nodeNumber - 10] : [item.toNodePosition_[0] - xDistance, item.toNodePosition_[1] + 15]
          for (let i = 0; i < nodeNumber; i++) {
            let textNode = new JTopo.TextNode(nameArray[i])
            // textNode.fontColor = '79, 160, 215'
            textNode.fontColor = '40,40,40'
            textNode.font = '600 15px 黑体'
            textNode.shadow = false
            textNode.dragable = false
            textNode.autoSize = false
            textNode.showSelected = false
            textNode.setLocation(twoLevelStartPosition[0], twoLevelStartPosition[1] + lineHeight * i)
            this.scene.add(textNode)
          }
        }
      }
    }
  },
  /** 组件创建 */
  created() {}
}
